home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 365_02 / sysdos.c < prev    next >
C/C++ Source or Header  |  1992-04-04  |  4KB  |  159 lines

  1. /* sysdos.c  -- DOS version of system.c */
  2.  
  3. /* Author:
  4.  *    Guntram Blohm
  5.  *    Buchenstrasse 19
  6.  *    7904 Erbach, West Germany
  7.  *    Tel. ++49-7305-6997
  8.  *    sorry - no regular network connection
  9.  */
  10.  
  11.  
  12. /* This file is derived from Steve Kirkendall's system.c.
  13.  *
  14.  * Entry points are:
  15.  *    system(cmd)    - run a single shell command
  16.  *    wildcard(names)    - expand wildcard characters in filanames
  17.  *
  18.  * This file is for use with DOS and TOS. For OS/2, slight modifications
  19.  * might be sufficient. For UNIX, use system.c. For Amiga, completely
  20.  * rewrite this stuff.
  21.  *
  22.  * Another system function, filter, is the same on DOS and UNIX and thus
  23.  * can be found in the original system.c.
  24.  */
  25.  
  26. #include "config.h"
  27. #include "vi.h"
  28. extern char **environ;
  29.  
  30.  
  31. #if MSDOS
  32. #include <process.h>
  33. extern unsigned char _osmajor;
  34. #endif
  35. #if TOS
  36. #include <osbind.h>
  37. #endif
  38.  
  39.  
  40. #if MSDOS || TOS
  41. #include <string.h>
  42.  
  43. /*
  44.  * Calling command is a bit nasty because of the undocumented yet sometimes
  45.  * used feature to change the option char to something else than /.
  46.  * Versions 2.x and 3.x support this, 4.x doesn't.
  47.  *
  48.  * For Atari, some shells define a shortcut entry which is faster than
  49.  * shell -c. Also, Mark Williams uses a special ARGV environment variable
  50.  * to pass more than 128 chars to a called command.
  51.  * We try to support all of these features here.
  52.  */
  53.  
  54. int system(cmd)
  55.     const char    *cmd;
  56. {
  57. #if MSDOS
  58.     char *cmdswitch="/c";
  59.     if (_osmajor<4)
  60.         cmdswitch[0]=switchar();
  61.     return spawnle(P_WAIT, o_shell, o_shell, cmdswitch, cmd, (char *)0, environ);
  62. #else
  63.     long    ssp;
  64.     int    (*shell)();
  65.     char    line[130];
  66.     char    env[4096], *ep=env;
  67.     int    i;
  68.  
  69. /* does our shell have a shortcut, that we can use? */
  70.  
  71.     ssp = Super(0L);
  72.     shell = *((int (**)())0x4F6);
  73.     Super(ssp);
  74.     if (shell)
  75.         return (*shell)(cmd);
  76.  
  77. /* else we'll have to call a shell ... */
  78.  
  79.     for (i=0; environ[i] && strncmp(environ[i], "ARGV=", 5); i++)
  80.     {    strcpy(ep, environ[i]);
  81.         ep+=strlen(ep)+1;
  82.     }
  83.     if (environ[i])
  84.     {
  85.         strcpy(ep, environ[i]); ep+=strlen(ep)+1;
  86.         strcpy(ep, o_shell); ep+=strlen(ep)+1;
  87.         strcpy(ep, "-c"); ep+=3;
  88.         strcpy(ep, cmd); ep+=strlen(ep)+1;
  89.     }
  90.     *ep='\0';
  91.     strcpy(line+1, "-c ");
  92.     strncat(line+1, cmd, 126);
  93.     line[0]=strlen(line+1);
  94.     return Pexec(0, o_shell, line, env);
  95. #endif
  96. }
  97.  
  98. /* This private function opens a pipe from a filter.  It is similar to the
  99.  * system() function above, and to popen(cmd, "r").
  100.  * sorry - i cant use cmdstate until rpclose, but get it from spawnle.
  101.  */
  102.  
  103. static int cmdstate;
  104. static char output[80];
  105.  
  106. int rpipe(cmd, in)
  107.     char    *cmd;    /* the filter command to use */
  108.     int    in;    /* the fd to use for stdin */
  109. {
  110.     int    fd, old0, old1, old2;
  111.  
  112.     /* create the file that will collect the filter's output */
  113.     strcpy(output, o_directory);
  114.     if ((fd=strlen(output)) && !strchr("/\\:", output[fd-1]))
  115.         output[fd++]=SLASH;
  116.     strcpy(output+fd, SCRATCHIN+3);
  117.     mktemp(output);
  118.     close(creat(output, 0666));
  119.     if ((fd=open(output, O_RDWR))==-1)
  120.     {
  121.         unlink(output);
  122.         return -1;
  123.     }
  124.  
  125.     /* save and redirect stdin, stdout, and stderr */
  126.     old0=dup(0);
  127.     old1=dup(1);
  128.     if (in)
  129.     {
  130.         dup2(in, 0);
  131.         close(in);
  132.     }
  133.     dup2(fd, 1);
  134.  
  135.     /* call command */
  136.     cmdstate=system(cmd);
  137.  
  138.     /* restore old std... */
  139.     dup2(old0, 0); close(old0);
  140.     dup2(old1, 1); close(old1);
  141.  
  142.     /* rewind command output */
  143.     lseek(fd, 0L, 0);
  144.     return fd;
  145. }
  146.  
  147. /* This function closes the pipe opened by rpipe(), and returns 0 for success */
  148. int rpclose(fd)
  149.     int    fd;
  150. {
  151.     int    status;
  152.  
  153.     close(fd);
  154.     unlink(output);
  155.     return cmdstate;
  156. }
  157.  
  158. #endif
  159.